/**
 * Copyright (c) 2016-2019 九点科技 All rights reserved.
 *
 * http://www.9dyun.cn
 *
 * 版权所有，侵权必究！
 */
package com.dian.modules.base.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.map.MapUtil;
import com.alibaba.fastjson.JSON;
import com.dian.common.exception.RRException;
import com.dian.common.utils.*;
import com.dian.common.validator.ValidatorUtils;
import com.dian.common.validator.group.AddGroup;
import com.dian.common.validator.group.UpdateGroup;
import com.dian.common.vo.TreeVo;
import com.dian.modules.base.entity.ClassEntity;
import com.dian.modules.enums.base.Dist_IsSystemEnum;
import  com.dian.common.enums.ValidEnum;
import com.dian.modules.sys.entity.SysDistEntity;
import com.dian.modules.sys.redis.SysConfigRedis;
import com.dian.modules.sys.vo.DistVO;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.apache.commons.collections.CollectionUtils;
import cn.hutool.core.util.StrUtil;

import java.util.Collection;
import java.util.Map;
import java.util.List;
import java.util.ArrayList;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.transaction.annotation.Transactional;
import com.dian.common.server.CommonService;
import com.dian.modules.base.dao.DistDao;
import com.dian.modules.base.entity.DistEntity;
import com.dian.modules.base.service.DistService;
import com.dian.modules.base.vo.DistExportVO;

/**
 * 业务数据字典服务实现类
 *
 * @author xiaolai
 * @email xiaolai@9dyun.cn
 * @date 2019-06-26 17:50:12
 */
@Service("sysdistService")
public class DistServiceImpl extends ServiceImpl<DistDao, DistEntity> implements DistService {

    protected Logger logger = LoggerFactory.getLogger(getClass());

    @Autowired
    public CommonService commonService;

    @Autowired
    private SysConfigRedis sysConfigRedis;

    /**
     * 查询所有
     * @return
     */
    @Override
    public Collection queryCacheAll() {
           Collection list=sysConfigRedis.getBaseDistList(commonService.getTenantId()+":dist:*");
            if(CollectionUtils.isEmpty(list)){
                list=Lists.newArrayList();
                for (DistEntity distEntity : getLists()) {

                    DistVO distVO=new DistVO();
                    distVO.setDistCode(distEntity.getDistCode());
                    distVO.setDistData(convertVo(distEntity.getDistLineData()));
                    sysConfigRedis.setBaseDist(commonService.getTenantId(),distVO,distEntity.getDistCode());
                    list.add(distVO);
                }
            }
            return list;
    }
    /**
     * 业务数据字典分页
     * @param params
     * @return
     */
    @Override
    public PageUtils queryPage(Map<String, Object> params) {

        IPage<DistEntity> page = this.page(new Query<DistEntity>().getPage(params),getQueryWrapper(params) );
        return new PageUtils(page);
    }

    /**
     *  业务数据字典新增
     * @param distEntity
     * @return
     */
    @Override
    @Transactional(rollbackFor = Throwable.class)
    public boolean saveInfo(DistEntity distEntity) {

        //设置编码，等基础默然初始化数据设置
        //数据完整性校验
        this.paramsCheck(distEntity,AddGroup.class);

        //保存
        this.save(distEntity);

        List<DistEntity> list= distEntity.getDistLineData();
        if (CollectionUtils.isNotEmpty(list)) {
            list.forEach(dist->{
                int curIndex = list.indexOf(dist)+1;
                dist.setParentId(distEntity.getId());
                dist.setDistName(distEntity.getDistName());
                dist.setDistCode(distEntity.getDistCode());
                dist.setIsSystem(1);
                dist.setConfSeq(curIndex);
                this.save(dist);
            });
        }

        DistVO distVO=new DistVO();
        distVO.setDistCode(distEntity.getDistCode());
        distVO.setDistData(convertVo(distEntity.getDistLineData()));
        sysConfigRedis.setBaseDist(commonService.getTenantId(),distVO,distEntity.getDistCode());
        return true;
    }

    /**
     *业务数据字典更新
     * @param distEntity
     * @return
     */
    @Override
    public boolean updateInfo(DistEntity distEntity) {

        //修改状态校验
        this.updateCheck(distEntity.getId());

        //主表数据完整性校验
        this.paramsCheck(distEntity, UpdateGroup.class);

        //更新主表
        this.updateById(distEntity);

        this.remove(new QueryWrapper<DistEntity>().in("parent_id",distEntity.getId()));

        List<DistEntity> list= distEntity.getDistLineData();
        if (CollectionUtils.isNotEmpty(list)) {
            list.forEach(dist->{
                int curIndex = list.indexOf(dist)+1;
                dist.setParentId(distEntity.getId());
                dist.setDistName(distEntity.getDistName());
                dist.setDistCode(distEntity.getDistCode());
                dist.setIsSystem(1);
                dist.setConfSeq(curIndex);
                this.save(dist);
            });
        }
        DistVO distVO=new DistVO();
        distVO.setDistCode(distEntity.getDistCode());
        distVO.setDistData(convertVo(distEntity.getDistLineData()));
        sysConfigRedis.setBaseDist(commonService.getTenantId(),distVO,distEntity.getDistCode());
        return true;
    }

    /**
     *业务数据字典删除
     * @param id
     * @return
     */
    @Override
    public boolean deleteInfo(Long id) {
        DistEntity distEntity = this.getById(id);
        //删除状态校验
        this.deleteCheck(distEntity);

        //更新主表
        this.remove(new QueryWrapper<DistEntity>().eq("id",id));
        //更新主表
        this.remove(new QueryWrapper<DistEntity>().eq("parent_id",id));
        sysConfigRedis.delete(RedisKeys.getBaseDistKey(commonService.getTenantId(),distEntity.getDistCode()));
        return true;
    }

    /**
     * 业务数据字典详情
     * @param id
     * @return
     */
    @Override
    public DistEntity getInfo(Long id) {
        DistEntity distEntity =getById(id);
        if(distEntity.getParentId().equals(0L)){
            distEntity.setDistLineData(getChildsEntity(distEntity.getId()));
        }
        return distEntity;
    }

    /**
     * 业务数据字典审核
     * @param id
     * @return
     */
    @Override
    @Transactional(rollbackFor = Throwable.class)
    public boolean checkInfo(Long id) {
        DistEntity distEntity =this.getById(id);
        checkCheck(distEntity);
        //distEntity.setOrderState(OrderHead_OrderStateEnum.AUDITED.getValue());
        //distEntity.setOrderDate(new Date());
        ///distEntity.setCheckUserId(commonService.getUserId());
        //distEntity.setCheckUserName(commonService.getUserName());
        return this.updateById(distEntity);
    }


    @Override
    public List<TreeVo<DistEntity>> queryTreeAll(Map<String, Object> params) {
        TreeVo<DistEntity> treeVo=new TreeVo<>();
        treeVo.setChildren(getChilds(0L));
        treeVo.setId(0L);
        treeVo.setTitle("全部");
        treeVo.setSpread(true);
        return   CollUtil.newArrayList(treeVo);
    }


    /**
     *业务数据字典当前页or全部导出
     * @param params
     * @return
     */
    @Override
    public List<DistExportVO> exportList(Map<String, Object> params) {
        List<DistEntity> list;
        if(!StrUtil.isBlankIfStr(params.get("exprotType"))){
            list= this.page(new Query<DistEntity>().getPage(params),getQueryWrapper(params)).getRecords();
        }else{
            list= this.list(getQueryWrapper(params));
        }

        List<DistExportVO> resultList = new ArrayList<>();
        if(CollectionUtils.isNotEmpty(list)) {
            resultList = BeanConverter.convertList(list, DistExportVO.class);
        }
        return resultList;
    }



    /***********************************************************************************************/
    /****************************************** 私有方法 ********************************************/
    /***********************************************************************************************/

    private String convertVo(List<DistEntity> list){
        List<Map<String,String>> listDist=Lists.newArrayList();
        for (DistEntity distEntity : list) {
           Map<String,String> map=Maps.newLinkedHashMap();
            map.put("key", distEntity.getConfKey());
            map.put("value", distEntity.getConfValue());
            listDist.add(map);
        }
        return JSON.toJSONString(listDist);
    }
    private List<DistEntity> getLists(){
        List<DistEntity> list= Lists.newArrayList();
        for (DistEntity distEntity : list(getQueryWrapper(Maps.newLinkedHashMap()))) {
            list.add(this.getInfo(distEntity.getId()));
        }
        return list;
    }
    //获取子节点数据
    private List<TreeVo<DistEntity>> getChilds(Long distId){
        List<TreeVo<DistEntity>> list=new ArrayList<>();
        List<DistEntity> listDistEntity=this.getChildsEntity(distId);
        for (DistEntity distEntity:listDistEntity){
            TreeVo<DistEntity> treeVo=new TreeVo<>();
            treeVo.setId(distEntity.getId());
            treeVo.setTitle(distEntity.getDistName());
            treeVo.setSpread(true);
            list.add(treeVo);
        }
        return list;
    }
    //获取子节点数据
    private List<DistEntity> getChildsEntity(Long distId){
        QueryWrapper query= new QueryWrapper<DistEntity>();
        query.eq("parent_id",distId);
        query.eq("is_valid", ValidEnum.YES.getValue());
        query.orderByAsc("conf_seq");
        List<DistEntity> listDistEntity=this.list(query);
        return listDistEntity;
    }

    /**
     * 修改状态校验
     *
     * @param
     */
    private void updateCheck(Long id) {
        DistEntity distEntity =this.getById(id);
        //if(distEntity.getOrderState().equals(OrderHead_OrderStateEnum.AUDITED.getValue())){
        //    throw new RRException(String.format("已审核的销售订单禁止修改"));
        //}
    }
    /**
     * 审核状态校验
     *
     * @param
     */
    private void checkCheck(DistEntity distEntity) {
        //if(distEntity.getOrderState().equals(OrderHead_OrderStateEnum.AUDITED.getValue())){
        //    throw new RRException(String.format("[%s] 此销售单已审核"));
        //}
    }

    /**
     * 删除状态校验
     *
     * @param distEntity
     */
    private void deleteCheck( DistEntity distEntity) {
        if(distEntity.getIsSystem().equals(Dist_IsSystemEnum.YES.getValue())){
            throw new RRException(String.format("系统业务数据字典不允许删除"));
        }
    }

    /**
     * 新增和修改参数校验
     *
     * @param record
     */
    private void paramsCheck(DistEntity record, Class<?> cls) {
        record.setParentId(0L);
        record.setIsSystem(1);
        QueryWrapper<DistEntity> queryWrapper=new QueryWrapper<>();
        queryWrapper.eq("dist_code",record.getDistCode());
        if(record.getId()!=null){
            queryWrapper.ne("id",record.getId());
            queryWrapper.eq("parent_id",0L);

        }
        int nCount=this.baseMapper.selectCount(queryWrapper);
        if(nCount>0){
            throw new RRException(String.format("已经存在 %s 编码",record.getDistCode()));
        }
        ValidatorUtils.validateEntity(record, cls);
    }
    /**
     * 获取查询条件
     *
     * @param
     */
    private QueryWrapper<DistEntity> getQueryWrapper(Map<String, Object> params) {
        QueryWrapper<DistEntity> queryWrapper=new QueryWrapper<>();
        if(!StrUtil.isBlankIfStr(params.get("distCode"))){
            queryWrapper.likeLeft("dist_code",params.get("distCode"));
        }
        if(!StrUtil.isBlankIfStr(params.get("distName"))){
            queryWrapper.likeLeft("dist_name",params.get("distName"));
        }
        queryWrapper.eq("parent_id",0L);
        queryWrapper.orderByAsc("id");
        return queryWrapper;
    }
}
